using System;
using System.Collections.Generic;
using UnityEngine;

namespace FrameWork
{
    public class Fsm<T> : FsmBase, IReference where T : class
    {
        private T _owner;

        private int _serializeId;

        public override Type OwnerType => _owner.GetType();

        public override int Id => _serializeId;

        /// <summary>
        /// 状态机的所有状态
        /// </summary>
        private Dictionary<Type, FsmState<T>> _states;

        /// <summary>
        /// 状态机当前状态
        /// </summary>
        private FsmState<T> _curState;

        /// <summary>
        /// 创建一个Fsm
        /// </summary>
        public static Fsm<T> Create(int id,T owner, List<FsmState<T>> states)
        {
            Fsm<T> fsm = ReferencePool.Acquire<Fsm<T>>();
            fsm._serializeId = id;
            fsm._owner = owner;
            fsm.RegisterStates(states);
            return fsm;
        }

        /// <summary>
        /// 开始有限状态机
        /// </summary>
        /// <typeparam name="TState"></typeparam>
        public void Start<TState>() where TState:FsmState<T>
        {
            Type t = typeof(TState);
            if(!_states.TryGetValue(t,out FsmState<T> resultState))
            {
                Debug.LogError("无法获取该状态");
                return;
            }

            _curState = resultState;
            _curState.OnInit(this);
        }

        /// <summary>
        /// 修改状态
        /// </summary>
        public void ChangeState<TState>() where TState : FsmState<T>
        {
            Type t = typeof(TState);
            if (!_states.TryGetValue(t, out FsmState<T> resultState))
            {
                Debug.LogError($"状态机不包括该状态{t}!!");
                return;
            }

            if (_curState != null)
            {
                _curState.OnLeave(this);
            }
            _curState = resultState;
            _curState.OnEnter(this);
        }

        public override void Update(float deltaTime)
        {
            if(_curState != null)
            {
                _curState.OnUpdate(this, deltaTime);
            }
        }

        private void RegisterStates(List<FsmState<T>> states)
        {
            if (_states == null)
                _states = new Dictionary<Type, FsmState<T>>();

            _states.Clear();
            foreach (FsmState<T> fsmState in states)
            {
                Type stateType = fsmState.GetType();
                if (!_states.TryAdd(stateType, fsmState))
                {
                    Debug.LogError("状态中已经有重复的状态了!");
                    continue;
                }
            }
        }

        public void Clear()
        {
            _states.Clear();
        }

        public override void ShowDown()
        {
            _curState.OnDestroy(this);
            _curState = null;
        }
    }
}

